package cn.ppool.xmlmapper.router;

import cn.ppool.xmlmapper.builder.MapperBuilder;
import cn.ppool.xmlmapper.builder.parse.Mapper;
import cn.ppool.xmlmapper.builder.parse.model.base.BaseEntryBO;
import cn.ppool.xmlmapper.builder.parse.model.entry.SelectBO;
import cn.ppool.xmlmapper.builder.parse.worker.WorkStackRecord;
import cn.ppool.xmlmapper.router.eneity.ConfigureDTO;
import cn.ppool.xmlmapper.router.eneity.EntryDTO;
import cn.ppool.xmlmapper.utils.ResponseDTO;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/xmlsql/api/")
public class ApiRouter {

    private ApplicationContext context;
    Map<String, MapperBuilder> configureList = new HashMap<>();

    public ApiRouter(ApplicationContext context) {
        this.context = context;
        getConfigure();
    }


    private void getConfigure() {
        Map<String, MapperBuilder> beans = context.getBeansOfType(MapperBuilder.class);
        configureList = beans;
    }

    @RequestMapping(value = "/getAllConfigure", method = RequestMethod.POST)
    @ResponseBody
    public Object getAllConfigure() {
        List<ConfigureDTO> beanNames = new ArrayList<>();
        for (Map.Entry<String, MapperBuilder> bean : configureList.entrySet()) {
            ConfigureDTO dto = new ConfigureDTO();
            dto.setBeanName(bean.getKey());
            beanNames.add(dto);
        }
        return ResponseDTO.OK(0, "", beanNames);
    }

    @RequestMapping(value = "/getConfigureAllNamespace", method = RequestMethod.POST)
    @ResponseBody
    public Object getConfigureAllNamespace(@RequestBody ConfigureDTO configureDTO) {
        List<EntryDTO> ens = new ArrayList<>();
        MapperBuilder configure = configureList.get(configureDTO.getBeanName());
        for (Map.Entry<String, Mapper> s : configure.getMapperList().entrySet()) {
            EntryDTO dto = new EntryDTO();
            dto.setBeanName(configureDTO.getBeanName());
            dto.setNamespace(s.getValue().getNamespace());
            int successCount = 0;
            int failCount = 0;
            int queryCount = 0;
            for (Map.Entry<String, BaseEntryBO> ss : s.getValue().getAllEntry().entrySet()) {
                WorkStackRecord stack = ss.getValue().getWorkRecord();
                queryCount += stack.getAddCount();
                successCount += stack.getAddCount() - stack.getErrorCount();
                failCount += stack.getErrorCount();
            }
            dto.setSuccessCount(successCount);
            dto.setErrorCount(failCount);
            dto.setQueryCount(queryCount);
            dto.setSuccessCount(successCount);
            ens.add(dto);
        }
        return ResponseDTO.OK(0, "", ens);
    }

    @RequestMapping(value = "/getAllEntry", method = RequestMethod.POST)
    @ResponseBody
    public Object getAllEntry(@RequestBody ConfigureDTO configureDTO) {
        List<EntryDTO> dto = new ArrayList<>();
        Mapper map = configureList.get(configureDTO.getBeanName()).getMapperList().get(configureDTO.getNamespace());
        for (BaseEntryBO entryBO : map.getAllEntry().values()) {
            EntryDTO entry = new EntryDTO();
            entry.setBeanName(configureDTO.getBeanName());
            entry.setNamespace(configureDTO.getNamespace());
            //
            if (entryBO instanceof SelectBO) {
                SelectBO select = (SelectBO) entryBO;
                entry.setReturnClass(select.getResultType().getName());
            }
            entry.setQueryCount(entryBO.getWorkRecord().getAddCount());
            entry.setErrorCount(entryBO.getWorkRecord().getErrorCount());
            entry.setSuccessCount(entryBO.getWorkRecord().getAddCount() - entryBO.getWorkRecord().getErrorCount());
            entry.setInitTime(entryBO.getInitTime());
            entry.setId(entryBO.getId());
            entry.setHasAnnotaion(entryBO.getFunAnt() != null);
            entry.setOriginSql(entryBO.getOriginSql());
            entry.setFunc(entryBO.getFun());
            dto.add(entry);
        }
        return ResponseDTO.OK(0, "", dto);
    }

    @RequestMapping(value = "/getWorkStatus", method = RequestMethod.POST)
    @ResponseBody
    public Object getWorkStatus(@RequestBody EntryDTO entryDTO, @RequestParam(defaultValue = "0") int thisPage, @RequestParam(defaultValue = "10") int pageNum) {
        Mapper map = configureList.get(entryDTO.getBeanName()).getMapperList().get(entryDTO.getNamespace());
        BaseEntryBO entryBO = map.getEntry(entryDTO.getId());
        return ResponseDTO.OK(0, "", entryBO.getWorkRecord().get(pageNum, thisPage));
    }

    @RequestMapping(value = "/clearWorkStatus", method = RequestMethod.POST)
    @ResponseBody
    public Object clearWorkStatus(@RequestBody EntryDTO entryDTO) {
        Mapper map = configureList.get(entryDTO.getBeanName()).getMapperList().get(entryDTO.getNamespace());
        map.getEntry(entryDTO.getId()).getWorkRecord().clear();
        return ResponseDTO.OK(0, "");
    }

}
